#pragma once

#include <cstdint>
#include <stdint.h>

#include "luster_ownership.hh"
#include "luster_status.hh"
#include "luster_string.hh"
#include "luster_vec.hh"

namespace luster {

#define SUBPROC_CHILD_SIZE (16)

struct Child {
	char payload_[SUBPROC_CHILD_SIZE];
};

struct Cmd {
	Vec<StringBuffer> args;
};

static inline void cmd_clear(Cmd *cmd) {
	vec_clear(&cmd->args);
}

luster_DROP(Cmd, cmd) {
	cmd_clear(cmd);
}

static inline void cmd_append(Cmd *cmd, char const *text) {
	stringbuf_append_cstring(vec_append_zero(&cmd->args), text);
}

Child cmd_spawn(Cmd *cmd);
Status child_wait(Child *child);

Status cmd_run(Cmd *cmd);

//
// Pool
//

struct ChildPool {
	Vec<Child> ring;
	uint64_t iget{0};
	uint64_t iput{0};
};

luster_DROP(ChildPool, pool) {
	vec_clear(&pool->ring);
	pool->iget = 0;
	pool->iput = 0;
};

void child_pool_init(ChildPool *cp, uintptr_t maxproc);
void child_pool_deinit(ChildPool *cp);
Status child_pool_spawn(ChildPool *cp, Cmd *cmd);
Status child_pool_wait(ChildPool *cp);

} // namespace luster
